
#include <bur/plctypes.h>

#ifdef _DEFAULT_INCLUDES
	#include <AsDefault.h>
#endif
#include <string.h>

void _CYCLIC ProgramCyclic(void)
{
	switch (step)
	{

		case CTRACE_COMMAND:
		
			if(LoadTracePar <= 8)
				brsmemcpy((UDINT)&gCockpTracePar, (UDINT)&TraceParSave[LoadTracePar], sizeof(gCockpTracePar));
			if(SaveTracePar <= 8)
				brsmemcpy((UDINT)&TraceParSave[SaveTracePar], (UDINT)&gCockpTracePar, sizeof(gCockpTracePar));
			LoadTracePar = 255;
			SaveTracePar = 255;

			if(gCockpTrace.ErrorReset)
			{
				gCockpTrace.ErrorReset = 0;
				gCockpTrace.Configuring	= 0;
				gCockpTrace.Active		= 0;
				gCockpTrace.SavingData	= 0;
				gCockpTrace.Done		= 0;
				gCockpTrace.Error		= 0;
				gCockpTrace.StatusID	= 0;
			}

			else if(gCockpTrace.Start)
			{
				gCockpTrace.Start = 0;
				StartedImmediately = 0;
				step = CTRACE_RESET;
			}

			else if(gCockpTrace.StartImmediately)
			{
				gCockpTrace.StartImmediately = 0;
				StartedImmediately = 1;
				step = CTRACE_RESET;
			}

			else if(gCockpTrace.SaveDataAgain)
			{
				gCockpTrace.SaveDataAgain = 0;
				DataSaveCsv_0.Execute = 0;
				step = CTRACE_DATA_SAVE;
			}
		break;
		

		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		case CTRACE_RESET:

			gCockpTrace.Configuring	= 1;
			gCockpTrace.Active		= 0;
			gCockpTrace.SavingData	= 0;
			gCockpTrace.Done		= 0;
			gCockpTrace.Error		= 0;
			gCockpTrace.StatusID	= 0;

			ConfigCreate_0.Enable				= 0;
			ConfigSetTiming_0.Execute			= 0;
			ConfigOptionalParameter_0.Execute	= 0;
			ConfigAddStartTrigger_0.Execute		= 0;
			ConfigAddDataPoint_0.Execute		= 0;
			Recorder_0.Enable					= 0;
			DataSaveCsv_0.Execute				= 0;

			CntTrigger	=0;
			CntDP		=0;
		
			step = CTRACE_CFG_CREATE;
		break;

		
		
		case CTRACE_CFG_CREATE: 

			ConfigCreate_0.Enable = 1;
			
			if(ConfigCreate_0.Error)
			{
				StatusID = ConfigCreate_0.StatusID;
				step = CTRACE_ERROR;
			}
			else if(ConfigCreate_0.Active)
			{
				step = CTRACE_CFG_ADD_TIMING;
			}
		break;
		
		
		
		case CTRACE_CFG_ADD_TIMING:

			ConfigSetTiming_0.Execute				= 1;
			ConfigSetTiming_0.ConfigIdent			= ConfigCreate_0.ConfigIdent;
			ConfigSetTiming_0.TotalRecordingTime	= gCockpTracePar.Timing.TotalRecordingTime;
			ConfigSetTiming_0.TriggerOffsetTime		= gCockpTracePar.Timing.TriggerOffsetTime;
			
			if(ConfigSetTiming_0.Error)
			{
				StatusID = ConfigSetTiming_0.StatusID;
				step = CTRACE_ERROR;
			}
			else if(ConfigSetTiming_0.Done)
			{
				ConfigSetTiming_0.Execute = 0;
				step = CTRACE_CFG_ADD_OPT1;
			}
		break;
		
		
		
		case CTRACE_CFG_ADD_OPT1:

			ConfigOptionalParameter_0.Execute		= 1;
			ConfigOptionalParameter_0.ConfigIdent	= ConfigCreate_0.ConfigIdent;
			ConfigOptionalParameter_0.Parameter		= coTRACE_PARAM_PV_TASK_CLASS; // Sample Time PV_Trace
			ConfigOptionalParameter_0.Value			= gCockpTracePar.Timing.PvTaskClass;

			if(ConfigOptionalParameter_0.Error)
			{
				StatusID = ConfigOptionalParameter_0.StatusID;
				step = CTRACE_ERROR;
			}
			else if(ConfigOptionalParameter_0.Done)
			{
				ConfigOptionalParameter_0.Execute = 0;
				step = CTRACE_CFG_ADD_OPT2;
			}
		break;
		
		
		
		case CTRACE_CFG_ADD_OPT2:

			ConfigOptionalParameter_0.Execute		= 1;
			ConfigOptionalParameter_0.ConfigIdent	= ConfigCreate_0.ConfigIdent;
			ConfigOptionalParameter_0.Parameter		= coTRACE_PARAM_ACP_SAMPLE_TIME; // Sample Time ACOPOS Trace
			ConfigOptionalParameter_0.Value			= gCockpTracePar.Timing.AcpSampleTime;

			if(ConfigOptionalParameter_0.Error)
			{
				StatusID = ConfigOptionalParameter_0.StatusID;
				step = CTRACE_ERROR;
			}
			else if(ConfigOptionalParameter_0.Done)
			{
				ConfigOptionalParameter_0.Execute = 0;
				step = CTRACE_CFG_ADD_OPT3;
			}
		break;
		
		
		
		case CTRACE_CFG_ADD_OPT3:

			ConfigOptionalParameter_0.Execute		= 1;
			ConfigOptionalParameter_0.ConfigIdent	= ConfigCreate_0.ConfigIdent;
			ConfigOptionalParameter_0.Parameter		= coTRACE_PARAM_ACP_BUFFER_SIZE; // ACOPOS Trace buffer size
			ConfigOptionalParameter_0.Value			= gCockpTracePar.Timing.AcpTraceBuffer;

			if(ConfigOptionalParameter_0.Error)
			{
				StatusID = ConfigOptionalParameter_0.StatusID;
				step = CTRACE_ERROR;
			}
			else if(ConfigOptionalParameter_0.Done)
			{
				ConfigOptionalParameter_0.Execute = 0;
				step = CTRACE_CFG_ADD_TRIGGER;
			}
		break;
			
		
		
		case CTRACE_CFG_ADD_TRIGGER:

			if((StartedImmediately) || (CntTrigger >= 2) || (brsstrcmp((UDINT)&gCockpTracePar.StartTrigger[CntTrigger].DataPointName, (UDINT)&"") == 0))
			{
				step = CTRACE_CFG_ADD_DATAPOINT;
			}
			else
			{
				ConfigAddStartTrigger_0.Execute 	= 1;
				ConfigAddStartTrigger_0.ConfigIdent	= ConfigCreate_0.ConfigIdent;
				brsstrcpy((UDINT)&ConfigAddStartTrigger_0.DataPointName, (UDINT)&gCockpTracePar.StartTrigger[CntTrigger].DataPointName);
				ConfigAddStartTrigger_0.Condition	= gCockpTracePar.StartTrigger[CntTrigger].Condition;
				ConfigAddStartTrigger_0.Threshold	= gCockpTracePar.StartTrigger[CntTrigger].Threshold;
				ConfigAddStartTrigger_0.Window		= gCockpTracePar.StartTrigger[CntTrigger].Window;
	
				if(ConfigAddStartTrigger_0.Error)
				{
					StatusID = ConfigAddStartTrigger_0.StatusID;
					step = CTRACE_ERROR;
				}
				else if(ConfigAddStartTrigger_0.Done)
				{
					ConfigAddStartTrigger_0.Execute = 0;
					CntTrigger++;
				}
			}
		break;
		
		
		
		case CTRACE_CFG_ADD_DATAPOINT:

			if((CntDP >= 50) || (brsstrcmp((UDINT)&gCockpTracePar.DataPointName[CntDP], (UDINT)&"") == 0))
			{
				step = CTRACE_RECORDING;
			}
			else
			{
				ConfigAddDataPoint_0.Execute		= 1;
				ConfigAddDataPoint_0.ConfigIdent	= ConfigCreate_0.ConfigIdent;
				brsstrcpy((UDINT)&ConfigAddDataPoint_0.DataPointName, (UDINT)&gCockpTracePar.DataPointName[CntDP]);
	
				if(ConfigAddDataPoint_0.Error)
				{
					StatusID = ConfigAddDataPoint_0.StatusID;
					step = CTRACE_ERROR;
				}
				else if(ConfigAddDataPoint_0.Done)
				{
					ConfigAddDataPoint_0.Execute = 0;
					CntDP++;
				}
			}
		break;
		
		
		
		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		case CTRACE_RECORDING:

			Recorder_0.Enable		= 1;
			Recorder_0.ConfigIdent	= ConfigCreate_0.ConfigIdent;
			
			Recorder_0.ForceStartTrigger	= (gCockpTrace.ForceStartTrigger || StartedImmediately);
			Recorder_0.ForceStop			= gCockpTrace.ForceStop;

			if(	(Recorder_0.TraceStatus == coTRACE_WAIT_START_TRIGGER_STATE) ||
				(Recorder_0.TraceStatus == coTRACE_WAIT_STOP_EVENT_STATE) )
			{
				gCockpTrace.Configuring	= 0;
				gCockpTrace.Active		= 1;
				gCockpTrace.SavingData	= 0;
				gCockpTrace.Done		= 0;
				gCockpTrace.Error		= 0;
			}
			
			if(Recorder_0.Error)
			{
				StatusID = Recorder_0.StatusID;
				step = CTRACE_ERROR;
			}
			else if(Recorder_0.DataAvailable)
			{
				step = CTRACE_DATA_SAVE;
			}
		break;

		
				
		case CTRACE_DATA_SAVE:
			DataSaveCsv_0.Execute	= 1;
			DataSaveCsv_0.DataIdent	= Recorder_0.DataIdent;
			brsstrcpy((UDINT)&DataSaveCsv_0.FileName,		(UDINT)&gCockpTracePar.File.FileName);
			brsstrcpy((UDINT)&DataSaveCsv_0.FileDevice,		(UDINT)&gCockpTracePar.File.FileDevice);
			brsstrcpy((UDINT)&DataSaveCsv_0.ColumnSeparator,(UDINT)&gCockpTracePar.File.ColumnSeparator);
			brsstrcpy((UDINT)&DataSaveCsv_0.DecimalMark,	(UDINT)&gCockpTracePar.File.DecimalMark);

			gCockpTrace.Configuring	= 0;
			gCockpTrace.Active		= 0;
			gCockpTrace.SavingData	= 1;
			gCockpTrace.Done		= 0;
			gCockpTrace.Error		= 0;

			if(DataSaveCsv_0.Error)
			{
				StatusID = DataSaveCsv_0.StatusID;
				step = CTRACE_ERROR;
			}
			else if(DataSaveCsv_0.Done)
			{
				step = CTRACE_DONE;
			} 
		break;
		
		
		
		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		case CTRACE_DONE:
			brsstrcpy((UDINT)&TraceConvFileName, (UDINT)&DataSaveCsv_0.FileName);
			CmdTraceConvStart = 1;

			gCockpTrace.Configuring	= 0;
			gCockpTrace.Active		= 0;
			gCockpTrace.SavingData	= 0;
			gCockpTrace.Done		= 1;
			gCockpTrace.Error		= 0;
			gCockpTrace.StatusID	= 0;
			step = CTRACE_COMMAND;
		break;

		
		
		case CTRACE_ERROR:
			gCockpTrace.Configuring	= 0;
			gCockpTrace.Active		= 0;
			gCockpTrace.SavingData	= 0;
			gCockpTrace.Done		= 0;
			gCockpTrace.Error		= 1;
			gCockpTrace.StatusID	= StatusID;
			step = CTRACE_COMMAND;
		break;

	}

	
		
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
	CoTraceConfigCreate(&ConfigCreate_0);
	CoTraceConfigSetTiming(&ConfigSetTiming_0);
	CoTraceConfigOptionalParameter(&ConfigOptionalParameter_0);
	CoTraceConfigAddStartTrigger(&ConfigAddStartTrigger_0);
	CoTraceConfigAddDataPoint(&ConfigAddDataPoint_0);
	CoTraceRecorder(&Recorder_0);
	CoTraceDataSaveCsv(&DataSaveCsv_0);
	
	
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	gCockpTrace.ForceStartTrigger	= 0;
	gCockpTrace.ForceStop			= 0;

	gCockpTrace.WaitsOnStartTrigger	= Recorder_0.WaitsOnStartTrigger;
	gCockpTrace.WaitsOnStopEvent	= Recorder_0.WaitsOnStopEvent;
	gCockpTrace.RecorderState		= Recorder_0.TraceStatus;
	

	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	MaxValPerNode = 0;
	brsmemset((UDINT)&CntValPerNode, 0, sizeof(CntValPerNode));
	for(i=0; i<=49; i++)
	{
		if(brsstrcmp((UDINT)&gCockpTracePar.DataPointName[i], (UDINT)&"") == 0)
			break;
		else
		{
			AdrStringFound = (UDINT)strstr((char*)&gCockpTracePar.DataPointName[i], (char*)&".ST");
			if(AdrStringFound != 0)
			{
				AdrStringFound += 3;
				TraceNode = brsatoi((UDINT)AdrStringFound);
				CntValPerNode[TraceNode]++;
				if(CntValPerNode[TraceNode] > MaxValPerNode)
				{
					MaxValPerNode = CntValPerNode[TraceNode];
				}
			}
		}
	}
	if(MaxValPerNode > 0)
		gCockpTracePar.Timing.MaxTotalRecordingTime = gCockpTracePar.Timing.AcpTraceBuffer * 1024.0 / (4.0 * MaxValPerNode) * gCockpTracePar.Timing.AcpSampleTime;
	else
		gCockpTracePar.Timing.MaxTotalRecordingTime = gCockpTracePar.Timing.AcpTraceBuffer * 1024.0 / (4.0 * 1) * gCockpTracePar.Timing.AcpSampleTime;
		
		
	


	
		
}
